package com.ruijie.autotest.log.validation.hangzhoudewangxin.WIFILOGIN;

import com.google.common.base.CharMatcher;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.ruijie.autotest.log.common.sql.SqlField;
import com.ruijie.autotest.log.core.validate.IValidator;
import com.ruijie.autotest.log.impl.validate.SolidValueValidator;
import com.ruijie.autotest.log.impl.validate.SqlExistingValidator;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;

import javax.sql.DataSource;
import java.util.regex.Pattern;

@SpringBootConfiguration
public class Config {
	@Bean
	public DataSource dataSource() {
		return new ComboPooledDataSource("remote");
	}

	@Bean
	public IValidator authTypeValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.auth_type", dataSource);
	}

	@Bean
	public IValidator authAccountValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.auth_account", dataSource);
	}

	@Bean
	public IValidator idCodeValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.auth_account", dataSource);
	}

	@Bean
	public IValidator idTypeValidator(DataSource dataSource) {
		// FIXME 2021/1/12  wait for me!!!    mappedValidator
		return sqlExistingVerificationOf("eg_auth_log.auth_account", dataSource)
				.after(item -> String.valueOf(toIDType(item, item)));
	}

	@Bean
	public IValidator idNameValidator() {
		return new SolidValueValidator("");
	}

	@Bean
	public IValidator appCompanyValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.app_company_name", dataSource);
	}

	@Bean
	public IValidator appNameValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.app_software_name", dataSource);
	}

	@Bean
	public IValidator appVersionValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.app_version", dataSource);
	}

	@Bean
	public IValidator appAuthcodeValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.appid", dataSource);
	}

	@Bean
	public IValidator locationCodeValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("s_location.code", dataSource);
	}

	@Bean
	public IValidator locationTypeValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("s_location_type.name", dataSource);
	}

	@Bean
	public IValidator loginAtValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.start_time", dataSource);
	}

	@Bean
	public IValidator logoutAtValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.end_time", dataSource);
	}

	@Bean
	public IValidator macValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.mac", dataSource)
				.after(this::toMac);
	}

	@Bean
	public IValidator lanIpValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.ip_address", dataSource)
				.after(item -> String.valueOf(ipToLong(item)));
	}

	@Bean
	public IValidator sourceIp4Validator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.src_ip", dataSource)
				.after(item -> String.valueOf(reverseIPV4(item)));
	}

	@Bean
	public IValidator sourceIp6Validator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.src_ipv6", dataSource);
	}

	@Bean
	public IValidator sourceStartport4Validator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.src_port_start", dataSource);
	}

	@Bean
	public IValidator sourceEndport4Validator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.src_port_end", dataSource);
	}

	@Bean
	public IValidator sourceStartport6Validator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.src_port_start_v6", dataSource);
	}

	@Bean
	public IValidator sourceEndport6Validator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.src_port_start_v6", dataSource)
				.after(item -> String.valueOf(toEndPort6(Integer.parseInt(item), Integer.parseInt(item))));
	}

	@Bean
	public IValidator apidValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("s_device.mac", dataSource); // FIXME 2021/1/11  wait for me!!!    merged
	}

	@Bean
	public IValidator apmacValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.ap_mac", dataSource)
				.after(this::toApmac);
	}

	@Bean
	public IValidator longitudeValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.longitude", dataSource);
	}

	@Bean
	public IValidator latitudeValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.latitude", dataSource);
	}

	@Bean
	public IValidator rssiValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.terminal_field_strength", dataSource);
	}

	@Bean
	public IValidator sessionidValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.session_id", dataSource);
	}

	@Bean
	public IValidator xValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.x_coordinate", dataSource);
	}

	@Bean
	public IValidator yValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.y_coordinate", dataSource);
	}

	@Bean
	public IValidator imsiValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.imsi", dataSource);
	}

	@Bean
	public IValidator deviceIdValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.imei_esn_meid", dataSource);
	}

	@Bean
	public IValidator terminalSystemValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.os_name", dataSource);
	}

	@Bean
	public IValidator terminalBrandValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.brand", dataSource);
	}

	@Bean
	public IValidator terminalBrandtypeValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.model", dataSource);
	}

	@Bean
	public IValidator sourceValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("s_security_org.org_code", dataSource);
	}

	@Bean
	public IValidator ispIdValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("s_location.operator_net_id", dataSource);
	}

	@Bean
	public IValidator wanIpValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.src_ip", dataSource);
	}

	@Bean
	public IValidator sourcePortValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.src_port_start", dataSource);
	}

	@Bean
	public IValidator ssidValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.ssid", dataSource);
	}

	@Bean
	public IValidator associatedValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("eg_auth_log.ssid", dataSource);
	}

	@Bean
	public IValidator floorValidator(DataSource dataSource) {
		return sqlExistingVerificationOf("s_device.floor", dataSource);
	}

	@Bean
	public IValidator loginTypeValidator(DataSource dataSource) {
		return new SolidValueValidator("30"); // dead value
	}

	private SqlExistingValidator sqlExistingVerificationOf(String pattern, DataSource dataSource) {
		return new SqlExistingValidator(SqlField.createSqlField(dataSource, pattern));
	}

	private int toIDType(String authAccount, String idCode) {
		if (Pattern.compile("1\\d{10}").matcher(idCode).matches()) {
			return Integer.parseInt("20001");
		} else if (Pattern.compile("^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$").matcher(idCode).matches()) {
			return Integer.parseInt("10111");
		} else {
			if ((authAccount == null) || (authAccount.equals(""))) {
				return 0;
			} else {
				return Integer.parseInt("10990");
			}
		}
	}

	private String toMac(String mac) {
		String result = null;
		if (null != mac) {
			String tmp = CharMatcher.JAVA_LETTER_OR_DIGIT.retainFrom(mac);
			result = Joiner.on("-").join(Splitter.fixedLength(2).split(tmp));
		}
		return result.toUpperCase();
	}

	public static Long ipToLong(String strIp) {
		long[] ip = new long[4];
		//先找到IP地址字符串中.的位置
		int position1 = strIp.indexOf(".");
		int position2 = strIp.indexOf(".", position1 + 1);
		int position3 = strIp.indexOf(".", position2 + 1);
		//将每个.之间的字符串转换成整型
		ip[0] = Long.parseLong(strIp.substring(0, position1));
		ip[1] = Long.parseLong(strIp.substring(position1 + 1, position2));
		ip[2] = Long.parseLong(strIp.substring(position2 + 1, position3));
		ip[3] = Long.parseLong(strIp.substring(position3 + 1));
		return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
	}

	private static Long reverseIPV4(String actualValue) {
		if (actualValue.equals("")) {
			return 0L;
		}
		return ipToLong(actualValue);
	}

	private Integer toEndPort6(Integer srcPortStartV6, int sourceEndPort6) {
		if ((srcPortStartV6 == null) || (srcPortStartV6 != 0)) {
			return srcPortStartV6;
		}
		return sourceEndPort6;
	}

	private String toApmac(String mac) {
		String result = null;
		if (null != mac) {
			String tmp = CharMatcher.JAVA_LETTER_OR_DIGIT.retainFrom(mac);
			result = Joiner.on("-").join(Splitter.fixedLength(2).split(tmp));
		}
		return result.toUpperCase();
	}
}
